ngx.header.content_type = "text/html; charset=utf-8"

-- Debug
-- 检查URL参数 "ask" 是否为 "true"
-- if ngx.var.arg_ask == "true" then
--     -- -- 获取所有请求头
--     -- local headers = ngx.req.get_headers()
--     -- ngx.say("--- Detected ask=true, Printing All Request Headers ---")
--     -- ngx.say("------------------------------------------------------")
    
--     -- -- 遍历并打印每一个请求头
--     -- for key, value in pairs(headers) do
--     --     -- 有些请求头可能有多个值，以table形式存在，这里做个兼容处理
--     --     if type(value) == "table" then
--     --         ngx.say(key .. ": " .. table.concat(value, ", "))
--     --     else
--     --         ngx.say(key .. ": " .. value)
--     --     end
--     -- end

--     -- ===================================================================
--     -- Part 1: 获取访客真实IP地址 (根据您的要求更新)
--     -- 优先级: CF-Connecting-IP > EO-Connecting-IP > X-Forwarded-For > remote_addr
--     -- ===================================================================
--     local cf_ip = ngx.var.http_cf_connecting_ip
--     local eo_ip = ngx.var.http_eo_connecting_ip -- Nginx 会自动将 'EO-Connecting-IP' 转为 'http_eo_connecting_ip'
--     local xff = ngx.var.http_x_forwarded_for
--     local current_visitor_ip
--     if cf_ip and cf_ip ~= "" then
--         current_visitor_ip = cf_ip
--     elseif eo_ip and eo_ip ~= "" then
--         current_visitor_ip = eo_ip
--     elseif xff and xff ~= "" then
--         -- 遍历 X-Forwarded-For 列表，获取最后一个非空的IP地址
--         local ips = {}
--         for ip in string.gmatch(xff, "([^, ]+)") do
--             table.insert(ips, ip)
--         end
--         if #ips > 0 then
--             current_visitor_ip = ips[#ips]
--         else
--             current_visitor_ip = ngx.var.remote_addr -- 如果 XFF 格式异常，则降级
--         end
--     else
--         -- 如果以上所有头都不存在，则使用直接连接的IP
--         current_visitor_ip = ngx.var.remote_addr
--     end

--     ngx.say("CF-Connecting-IP: ", cf_ip)
--     ngx.say("EO-Connecting-IP: ", eo_ip)
--     ngx.say("X-Forwarded-For: ", xff)
--     ngx.say("Current Visitor IP: ", current_visitor_ip)
    
--     ngx.say("--- All IPs in X-Forwarded-For ---")
--     if xff and xff ~= "" then
--         for ip in string.gmatch(xff, "([^, ]+)") do
--             ngx.say(ip)
--         end
--     else
--         ngx.say("X-Forwarded-For is empty or not present.")
--     end
    
--     ngx.say("------------------------------------------------------")
--     -- 打印完毕，正常退出，不再执行后面的统计代码
--     return ngx.exit(ngx.OK)
-- end

-- ======================================================
-- [[ 您原有的 stats.lua 代码从这里开始 ]]
-- ======================================================


-- status.lua (最终优化版 - 已确认能处理重复IP)

-- 获取当前访问者的真实 IP 地址
local xff = ngx.var.http_x_forwarded_for
local current_visitor_ip
if xff and xff ~= "" then
    -- 遍历 X-Forwarded-For 列表，获取最后一个非空的IP地址
    local ips = {}
    for ip in string.gmatch(xff, "([^, ]+)") do
        table.insert(ips, ip)
    end
    if #ips > 0 then
        current_visitor_ip = ips[#ips]
    else
        current_visitor_ip = ngx.var.remote_addr -- 如果 XFF 格式异常，则降级
    end
else
    current_visitor_ip = ngx.var.remote_addr
end

-- 字节转换
local function human_bytes(n)
    if not n then return "0 B" end
    if n < 1024 then return string.format("%d B", n) end
    if n < 1024 * 1024 then return string.format("%.2f KB", n / 1024) end
    if n < 1024 * 1024 * 1024 then return string.format("%.2f MB", n / (1024 * 1024)) end
    return string.format("%.2f GB", n / (1024 * 1024 * 1024))
end

-- 耗时转换
local function human_duration(us)
    if not us then return "0 μs" end
    return string.format("%d μs", us)
end

-- 获取限制阈值
local function get_limits(during)
    if during == "hour" then
        return {
            count = ngx.var.limit_count_per_hour,
            bytes = ngx.var.limit_bytes_per_hour,
            costs_us = tonumber(ngx.var.limit_costs_per_hour) * 1000
        }
    else -- day
        return {
            count = ngx.var.limit_count_per_day,
            bytes = ngx.var.limit_bytes_per_day,
            costs_us = tonumber(ngx.var.limit_costs_per_day) * 1000
        }
    end
end

-- 生成表格行
local function generate_table_rows(visitor_ip)
    local rows = ""
    local timestamp = ngx.now()
    local dict = ngx.shared.traffic_stats
    
    local function stats(during)
        local limits = get_limits(during)
        local bytes_limit_human = human_bytes(tonumber(limits.bytes))
        local costs_limit_human = human_duration(limits.costs_us)
        
        local keys = dict:get_keys(0)
        for _, val in pairs(keys) do
            local match = "last:"..during
            if val:sub(1, #match) == match then
                local ip = val:sub(#match + 2)
                
                -- 批量获取数据，减少竞态条件窗口
                local last_time = dict:get(val)
                local count = dict:get("count:"..during..":"..ip)
                local bytes = dict:get("bytes:"..during..":"..ip)
                local costs_us = dict:get("costs:"..during..":"..ip)
                local forbidden = dict:get("forbidden:"..during..":"..ip)

                -- 增加nil检查，如果数据在中途被删除，则跳过此条记录
                if last_time and count and bytes and costs_us then
                    local age = math.floor(timestamp - (tonumber(last_time) or timestamp))
                    local bytes_human = human_bytes(tonumber(bytes))
                    local costs_human = human_duration(tonumber(costs_us))
                    local forbidden_str = tostring(forbidden or false)

                    local row_style = ""
                    if ip == visitor_ip then
                        row_style = "style='background-color: #d4edda; font-weight: bold;'"
                    end
                    
                    rows = rows .. string.format([[
                        <tr %s>
                            <td class="ip-cell">%s</td>
                            <td>%s</td>
                            <td>%d</td>
                            <td>%d/%s</td>
                            <td>%s/%s</td>
                            <td>%s/%s</td>
                            <td>%s</td>
                            <td class="location-cell" data-ip="%s"></td>
                        </tr>
                    ]], 
                    row_style,
                    ip, during, age, 
                    tonumber(count), limits.count, 
                    bytes_human, bytes_limit_human, 
                    costs_human, costs_limit_human, 
                    forbidden_str,
                    ip
                    )
                end
            end
        end
    end
    
    stats("hour")
    stats("day")
    return rows
end

local request_type = ngx.var.arg_type or "page"

if request_type == "data" then
    ngx.say(generate_table_rows(current_visitor_ip))
else
    ngx.say([[
    <html>
    <head>
    <title>IP 限制与使用统计 (含归属地)</title>
    <style>
        body { font-family: sans-serif; }
        table { border-collapse: collapse; font-family: monospace; font-size: 14px; margin: 20px auto; width: 90%; max-width: 1600px; }
        th, td { border: 1px solid #ccc; padding: 8px 12px; text-align: center; }
        th { background: #f5f5f5; font-weight: bold; }
        .header-info { text-align: center; margin: 10px auto; }
        .update-time { text-align: center; margin-top: 10px; color: #666; font-size: 12px; }
        .location-cell { min-width: 180px; color: #337ab7; }
    </style>
    <script>
        // 在脚本顶部创建一个全局缓存对象
        const ipLocationCache = {};
        // 创建一个队列来管理待处理的IP请求
        let ipRequestQueue = [];
        let isProcessingQueue = false;

        // 处理IP请求队列的函数
        function processIpQueue() {
            if (ipRequestQueue.length === 0) {
                isProcessingQueue = false;
                return;
            }
            isProcessingQueue = true;
            
            const ip = ipRequestQueue.shift(); // 取出队列中的第一个IP

            // 更新UI状态为“查询中...”
            document.querySelectorAll(`.location-cell[data-ip='${ip}']`).forEach(c => {
                c.textContent = '查询中...';
            });

            fetch(`https://api.vore.top/api/IPdata?ip=${ip}`)
                .then(response => response.json())
                .then(data => {
                    let location = '查询失败';
                    if (data && data.ipdata && data.ipdata.info1) {
                        location = `${data.ipdata.info1} ${data.ipdata.info2 || ''} ${data.ipdata.info3 || ''}`.trim();
                    }
                    ipLocationCache[ip] = location;
                    document.querySelectorAll(`.location-cell[data-ip='${ip}']`).forEach(c => {
                        c.textContent = location;
                    });
                })
                .catch(error => {
                    console.error('Error fetching IP location for', ip, error);
                    const errorMessage = '查询出错';
                    ipLocationCache[ip] = errorMessage;
                    document.querySelectorAll(`.location-cell[data-ip='${ip}']`).forEach(c => {
                        c.textContent = errorMessage;
                    });
                })
                .finally(() => {
                    // 3秒后处理下一个IP
                    setTimeout(processIpQueue, 3000);
                });
        }

        // 更新IP归属地的函数，将IP加入队列
        function updateIPLocations() {
            document.querySelectorAll('.location-cell').forEach(cell => {
                const ip = cell.dataset.ip;
                if (!ip) return;
                
                if (ipLocationCache[ip]) {
                    cell.textContent = ipLocationCache[ip];
                } else {
                    cell.textContent = '排队中...';
                    // 如果IP不在队列中，则加入
                    if (!ipRequestQueue.includes(ip)) {
                        ipRequestQueue.push(ip);
                    }
                }
            });

            // 如果队列当前没有在处理，则开始处理
            if (!isProcessingQueue && ipRequestQueue.length > 0) {
                processIpQueue();
            }
        }

        // 封装数据获取和更新的逻辑
        function fetchAndUpdate() {
            fetch('/dk8s.stats?type=data&t=' + Date.now())
                .then(r => r.text())
                .then(data => {
                    document.getElementById('stats-body').innerHTML = data;
                    document.getElementById('last-update').textContent = new Date().toLocaleString();
                    updateIPLocations();
                });
        }

        // 页面加载完成后，立即执行一次
        document.addEventListener('DOMContentLoaded', fetchAndUpdate);

        // 每隔 5 秒刷新一次数据
        setInterval(fetchAndUpdate, 500);

    </script>
    </head>
    <body>
        <div class="header-info">
            <h3>Your Current IP: <span style="color: #007bff;">]] .. current_visitor_ip .. [[</span></h3>
        </div>
        <table>
            <thead>
                <tr>
                    <th>IP</th>
                    <th>周期</th>
                    <th>活跃时间(秒)</th>
                    <th>请求数(当前/限制)</th>
                    <th>流量(当前/限制)</th>
                    <th>耗时(当前/限制)</th>
                    <th>是否封禁</th>
                    <th>归属地</th>
                </tr>
            </thead>
            <tbody id="stats-body">
                ]] .. generate_table_rows(current_visitor_ip) .. [[
            </tbody>
        </table>
        <div class="update-time">
            最后更新: <span id="last-update">]] .. os.date("%Y-%m-%d %H:%M:%S") .. [[</span>
        </div>
    </body>
    </html>
    ]])
end
